#ifndef __polynomial_base_hh__
#define __polynomial_base_hh__

#include "point.hh"
#include "fem_types.hh"

template<typename T>
struct PolynomialTraits
{
};

template <unsigned int DIM, fastfem::PolynomialFamily PFAMILY, fastfem::FunctionSpace FETYPE, typename T=double, typename U=T>
class PolynomialBase
{
public:
  PolynomialBase(unsigned int p_order) : m_order(p_order)  { }
  virtual ~PolynomialBase() { }

  /** function which evaluates the values of the polynomial shape functions at a given point ip */
  virtual U evaluate_basis ( unsigned int , const Point<DIM, U>& ) const = 0;

  /** virtual function which evaluates the values of all shape functions at all point ips */
  virtual void evaluate_basis_all ( const PointList<DIM, U>& p_ips, std::vector<U>& p_basis_vals ) const = 0;

  virtual int print() const = 0 ;

  const std::vector<Point<DIM, T> >& get_nodes() const ;

  const std::vector<Point<DIM, T> >& get_weights() const ;
  
protected:

  // member data
  const unsigned int m_order ;

  std::vector<Point<DIM, T> > m_nodes;
  std::vector<T> m_weights;
  
};

// Inline methods

template <unsigned int DIM, fastfem::PolynomialFamily PFAMILY, fastfem::FunctionSpace FETYPE, typename T, typename U>
const std::vector<Point<DIM, T> >& PolynomialBase<DIM, PFAMILY, FETYPE, T, U>::get_nodes() const
{
  return m_nodes;
}

template <unsigned int DIM, fastfem::PolynomialFamily PFAMILY, fastfem::FunctionSpace FETYPE, typename T, typename U>
const std::vector<Point<DIM, T> >& PolynomialBase<DIM, PFAMILY, FETYPE, T, U>::get_weights() const
{
  return m_weights ;
}
  

#endif // #ifndef __polynomial_base_hh__

